<template lang="pug">
  div.dashboard-tree-wrapper
    <!--搜索框-->
    .dashboard-tree-search
      el-input(v-model="keyword",placeholder="搜索")
    <!--树-->
    ul#dashboard-tree.dashboard-tree-main.ztree
</template>

<script>
import Collect from './img/Collect.png'
import Root from './img/Root.png'
import Org from './img/Org.png'
import Area from './img/Area.png'
import Flux from './img/Flux.png'
import User from './img/User.png'
import { uniq, isEqual } from 'lodash'
export default {
  name: 'DashboardTree',
  props: {
    treeNodes: {
      type: Array,
      default: () => []
    },
    value: {
      type: Array,
      default: () => []
    }
  },
  data () {
    return {
      Collect: Collect,
      Root: Root,
      Org: Org,
      Area: Area,
      Flux: Flux,
      User: User,
      keyword: '',
      // ztree的配置
      setting: {
        data: {
          simpleData: {
            enable: true,
            idKey: 'id',
            pIdKey: 'parentId',
            rootPId: 0
          }
        },
        callback: {
          onCheck: this.treeCheck,
          beforeCheck: this.beforeTreeCheck,
          // 点击节点文本也触发check
          onClick: (e, treeId, treeNode, clickFlag) => {
            if (this.beforeTreeCheck(treeId, treeNode)) {
              this.treeObj.checkNode(treeNode, !treeNode.checked, true)
              this.treeCheck(null, treeId, treeNode)
            }
          }
        },
        check: {
          enable: true
        }
      }
    }
  },
  computed: {
    devices: {
      get () {
        return this.value
      },
      set (data) {
        this.$emit('input', data)
      }
    },
    decorativeTreeNodes () {
      // 站点树图标样式
      let data = this.treeNodes.map(item => {
        // let result = [Collect, Root, Org, Area, User, Flux]
        if (item.parentId === 0) {
          item.icon = this.Root
        } else if (item.isDevice) {
          item.icon = this.Area
        } else {
          item.icon = this.Org
        }
        return item
      })
      return data
    }
  },
  watch: {
    // 关键词的任何改变触发树的搜索
    keyword (data) {
      this.treeSearch(data)
    },
    devices (value, oldValue) {
      const newIds = value.map(({id}) => id)
      const oldIds = oldValue.map(({id}) => id)
      if (isEqual(newIds, oldIds)) {
        this.treeRender(value)
      }
    }
  },
  methods: {
    // 树的初始化
    treeInit () {
      // 把数据传入树的组件并把dom改成树
      this.$$.fn.zTree.init(this.$$('#dashboard-tree'), this.setting, this.decorativeTreeNodes)
      // 把树的DOM做赋给组件的treeObj,以便操作
      this.treeObj = this.$$.fn.zTree.getZTreeObj('dashboard-tree')
    },
    treeCheck (event, treeId, treeNode) {
      this.devices = this.treeObj.getCheckedNodes().filter(({isDevice}) => isDevice)
    },
    beforeTreeCheck (treeId, treeNode) {
      // wangrf 站点树勾选判断，待优化
      const allChildrenNode = this.getChildren(treeNode)
      if (treeNode.checked) {
        return true
      } else if (treeNode.children) {
        // console.log('点开文件夹', treeNode, allChildrenNode.length + this.devices.length)
        const devicesTypes = uniq([...this.devices, ...allChildrenNode].map(({deviceName}) => deviceName))
        if (allChildrenNode.length + this.devices.length <= 6 && devicesTypes.length === 1) {
          // console.log(allChildrenNode.length + this.devices.length)
          return true
        }
        this.$message({
          message: '请选择同一种类型设备且不超过六个',
          type: 'warning'
        })
        return false
      } else {
        // console.log('选中节点', treeId, treeNode)
        if (this.devices.length === 0 || this.devices.includes(treeNode)) {
          return true
        }
        // 超过六个取消勾选
        if (this.devices.length >= 6) {
          this.$message({
            message: '最多选择六个的设备进行对比',
            type: 'warning'
          })
          return false
        }
        // 判断是否选择了不同类型的设备
        if (this.devices !== 0 && this.devices[0].deviceName !== treeNode.deviceName) {
          this.$message({
            message: '请选择同一种类型的设备做对比',
            type: 'warning'
          })
          return false
        }
        return true
      }
    },
    getAllNode () {
      return this.treeObj.transformToArray(this.treeObj.getNodes())
    },
    // 输入节点，把其子孙节点找出来
    getChildren (node) {
      return node.children ? node.children.reduce((result, item) => {
        return [...result, ...this.getChildren(item)]
      }, node.children) : []
    },
    // 输入节点列表，把其祖先节点和子孙节点找出来, 并去重
    getTreeFamily (nodeList) {
      const arr = nodeList.reduce((result, item) => {
        return [...result, ...item.getPath(), ...this.getChildren(item)]
      }, [])
      return uniq(arr)
    },
    // 树的所有节点恢复全显示并收起的状态
    treeReverse () {
      this.treeObj.showNodes(this.treeObj.getNodesByParam('isHidden', true))
      this.treeObj.expandAll(false)
    },
    // 树的搜索
    treeSearch (keyword) {
      if (keyword === '') {
        this.treeReverse()
      } else {
        // 把树的数据扁平化
        const allNodes = this.getAllNode()
        // 隐藏所有数据
        this.treeObj.hideNodes(allNodes)
        // 树里面的name当做关键词匹配出来
        const nodeList = this.treeObj.getNodesByParamFuzzy('name', keyword, 0)
        // 把找出来的结果去重后显示出来
        this.treeObj.showNodes(this.getTreeFamily(nodeList))
        // 所有节点展开
        this.treeObj.expandAll(true)
      }
    },
    // 树随着传入的deviceIds联动
    treeRender (deviceIds) {
      if (this.treeObj) {
        this.treeReverse()
        this.treeObj.checkAllNodes(false)
        const nodeList = this.treeObj.getNodesByFilter((node) => {
          return deviceIds.includes(node.siteId)
        })
        nodeList.forEach((node) => {
          this.treeObj.checkNode(node, true, true)
        })
        const nodeFamily = this.getTreeFamily(nodeList)
        nodeFamily.forEach((node) => {
          this.treeObj.expandNode(node)
        })
      }
    }
  },
  mounted () {
    // 树的初始化
    this.treeInit()
    // this.getAllNode().map(item => {
    //   item.icon = './assets/img/ztree/node1.png'
    // })
  }
}
</script>
<style lang="sass" scoped>
.dashboard-tree-wrapper
  flex: 1
  display: flex
  flex-direction: column
.dashboard-tree-search
  padding: 12px
.dashboard-tree-main
  flex: 1
  display: flex
  overflow: auto
</style>
